home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / VideoToolbox 96.06.15 / (Demos) / Filter.c < prev    next >
C/C++ Source or Header  |  1996-01-25  |  9KB  |  263 lines

  1. /* Filter.c
  2. © 1989-1995 Denis G. Pelli 
  3. Display one letter and low-pass filter it.
  4. Also display a gray wedge, to confirm that lookup table has been correctly loaded.
  5.  
  6. NOTE:
  7. Calling ShieldCursor() has two desirable effects, one direct, one indirect.
  8. Firstly, it keeps the cursor from messing up the grating that we're drawing.
  9. Secondly, ShieldCursor() is the trap that non-standard QuickDraw devices patch in order
  10. to find out what parts of the screen have been updated. Thus the call to ShieldCursor()
  11. will make the grating show up on a Radius PowerView, which drives a video monitor via
  12. SCSI, and needs to know when to copy new info from the memory buffer to the
  13. screen device. My understanding is that all QuickDraw drawing operations automatically
  14. call ShieldCursor() & ShowCursor(), so this is only relevant when we draw bypassing
  15. QuickDraw, i.e. by calling SetPixelsQuickly or CopyBitsQuickly. CopyWindows() calls
  16. ShieldCursor and ShowCursor for you.
  17.  
  18. HISTORY:
  19. 3/31/89 dgp Wrote it, based on simple program by Preeti Verghese & Mike Schechter,
  20.             which just displayed a character.
  21. 4/25/89 dgp added code to linearize the clut. Locked the window's pixmap.
  22. 10/9/89 dgp    Updated it to use SetLuminances, etc.
  23. 7/10/90 dgp Changed the declaration of window to be a CWindowPtr.
  24.             Added “done” message.
  25. 10/11/90 dgp Added fpu test.
  26. 10/12/90 dgp Changed LuminanceRecord.h to LuminanceRecord1.h
  27. 2/27/91    dgp     Tidied up.
  28. 8/24/91    dgp    Made compatible with THINK C 5.0.
  29. 2/15/92    dgp    Incorporated Larry Cormack's suggestion of shrinking the console
  30.             so as not to obscure the main window.
  31. 7/20/92    dgp    added printf of done message
  32. 8/27/92    dgp    replace SysEnvirons() by Gestalt()
  33. 1/4/93    dgp    Don't call SetLuminances if device is of fixedType.
  34. 2/7/93    dgp    Updated to use SetPixelsQuickly. Tidied up the grayscale wedge.
  35.             Recompiled with the new ConvolveX.c, which has better rounding.
  36. 2/8/93    dgp    Recompiled with the new ConvolveX.c, overflow bug now fixed.
  37. 7/7/93    dgp    Made rect a tad bigger to allow for slant of italic.
  38. 6/23/94    dgp    Use Choose().
  39. 4/11/95 dgp Save and restore the display depth and color mode.
  40. 6/14/95 dgp added calls to ShieldCursor().
  41. 1/25/96 dgp ConvolveX.c is incompatible with 16 & 32-bit depths, so we set depth to 8 or less.
  42.             Restore original depth on exit.
  43. */
  44. #include "VideoToolbox.h"
  45. #include "Luminance.h"
  46. //#include <Fonts.h>
  47. #if UNIVERSAL_HEADERS
  48.     #include <LowMem.h>
  49. #else
  50.     #define LMGetMBarHeight() (* (short *) 0x0BAA)
  51.     #define LMSetMBarHeight(MBarHeightValue) ((* (short *) 0x0BAA) = (MBarHeightValue))
  52. #endif
  53. #define SIZE 127        /* point size of text to be filtered */
  54. #define DIM 64            /* size of point spread function, sigma=DIM/4 */
  55.  
  56. void Filter(void);
  57.  
  58. void main(void)
  59. {
  60.     StackGrow(1000+sizeof(luminanceRecord)+512*sizeof(long));
  61.     Require(gestalt8BitQD);
  62.     Filter();
  63. }
  64. void Filter(void)
  65. {
  66.     EventRecord event;
  67.     register short i;
  68.     int j,clutSize,dim=DIM,error;
  69.     short preferredPixelSize[]={8,4,2,1};    // Order of preference
  70.     short pixelSize,oldPixelSize,oldIsColor,mode;
  71.     short textSize=SIZE,FontNum;
  72.     unsigned char *s;
  73.     char string[64];
  74.     Rect r,dstRect,wedge;
  75.     CWindowPtr window,oldPort;
  76.     GDHandle device,oldDevice;
  77.     double f[DIM],contrast,a,c,sigma;
  78.     luminanceRecord LR,*LP;
  79.     unsigned long row[512];
  80.     Boolean attenuator;
  81.     RGBColor blackRGB={0,0,0},whiteRGB={0xffff,0xffff,0xffff};
  82.     Point pt;
  83.     long multiplier;
  84.     RGBColor rgb;
  85.  
  86.     assert(StackSpace()>5000);
  87.     /* Gaussian point spread function, normalized to unit integral. */
  88.     sigma=dim/4.0;
  89.     c=0.0;
  90.     for(i=0;i<dim;i++) {
  91.         a=(i-(dim-1)/2.0)/sigma;
  92.         f[i]=exp(-a*a);
  93.         c+=f[i];
  94.     }
  95.     for(i=0;i<dim;i++) f[i] /= c;
  96.  
  97.     /* INITIALIZE QuickDraw */
  98.     #if (THINK_C || THINK_CPLUS || SYMANTEC_C)
  99.         console_options.nrows = 5;
  100.         console_options.left=32;
  101.     #elif __MWERKS__
  102.         SIOUXSettings.toppixel=LMGetMBarHeight()+19;    // allow for menu bar and title bar
  103.         SIOUXSettings.leftpixel=1;
  104.         SIOUXSettings.rows=5;
  105.         SIOUXSettings.autocloseonquit=0;
  106.         SIOUXSettings.showstatusline=0;
  107.         SIOUXSettings.asktosaveonclose=0;
  108.         printf("\n");
  109.     #elif
  110.         InitGraf(&qd.thePort);
  111.         InitFonts();
  112.         InitWindows();
  113.         InitCursor();
  114.     #endif
  115.     printf("\n");
  116.     GetGWorld(&oldPort,&oldDevice);
  117.  
  118.     printf("Welcome to Filter.\n");
  119.     /* Find device corresponding to the experimental screen. */
  120.     for(i=8;i>=0;i--){
  121.         device = GetScreenDevice(i);
  122.         if(device!=NULL) break;
  123.     }
  124.     do{
  125.         if(GetScreenDevice(1)!=NULL)i=ChooseScreen(i,"Which screen?");
  126.         else i=0;
  127.         device=GetScreenDevice(i);
  128.     }while(device==NULL);
  129.  
  130.     pixelSize=(**(**device).gdPMap).pixelSize;
  131.     oldIsColor=TestDeviceAttribute(device,gdDevType);
  132.     clutSize=GDClutSize(device);
  133.     printf("%d colors.\n",clutSize);
  134.  
  135.     /* Use results of last screen calibration to do gamma correction */
  136.     #include "LuminanceRecord1.h"
  137.     LP=&LR;
  138.     attenuator=Choose(0,"Have you installed an ISR Video Attenuator on that monitor?\n"
  139.         ,noYes,2);
  140.     window = GDOpenWindow(device);
  141.     if(!attenuator){
  142.         LP->r=0.0;
  143.         LP->g=1.0;
  144.         LP->b=0.0;
  145.     }
  146.  
  147.     // Try to get the best possible pixelSize.
  148.     oldPixelSize=(**(**device).gdPMap).pixelSize;
  149.     oldIsColor=TestDeviceAttribute(device,gdDevType);
  150.     if(oldPixelSize!=preferredPixelSize[0] && NewPaletteManager()){
  151.         for(i=0;i<sizeof(preferredPixelSize)/sizeof(*preferredPixelSize);i++){
  152.             if(oldPixelSize==preferredPixelSize[i] && oldIsColor)break;
  153.             mode=HasDepth(device,preferredPixelSize[i],0,0);
  154.             if(mode!=0){
  155.                 printf("Changing pixelSize to %d bits, color.\n",(int)preferredPixelSize[i]);
  156.                 error=SetDepth(device,preferredPixelSize[i],1<<gdDevType,1);    // color
  157.                 break;
  158.             }
  159.         }
  160.     }
  161.     pixelSize=(**(**device).gdPMap).pixelSize;
  162.  
  163.     // if not already in color mode, switch to color mode
  164.     if(!oldIsColor)error=SetDepth(device,(**(**device).gdPMap).pixelSize,1<<gdDevType,1);
  165.     if((*device)->gdType!=fixedType) SetLuminances(device,&LR,0,clutSize-1,0.0,LP->LMax);
  166.  
  167.     contrast = 1.0;
  168.     if(0){
  169.         printf("Contrast? (%f) ",contrast);
  170.         gets(string);
  171.         sscanf((char *)string,"%lf",&contrast);
  172.         printf("=%f\n",contrast);
  173.     }
  174.  
  175.     switch(pixelSize){
  176.         case 32: multiplier=256;
  177.         break;
  178.         case 16: multiplier=32;
  179.         break;
  180.         default: multiplier=1;
  181.     }
  182.  
  183.     /* Display text */
  184.     SetPort((WindowPtr)window);
  185.     BringToFront((WindowPtr)window);
  186.     PmForeColor(0);                    /* black in our current clut */
  187.     PmBackColor(multiplier*(clutSize-1));        /* white in our current clut */
  188.     EraseRect(&window->portRect);    /* Fill with background color */
  189.     GetFNum((StringPtr)"\pHelvetica",&FontNum);
  190.     TextFont(FontNum);
  191.     TextFace(bold+italic);
  192.     TextSize(textSize);
  193.     j=(unsigned int)((1.0 - contrast)*(clutSize-1));
  194.     PmForeColor(multiplier*j);
  195.     Index2Color(multiplier*j,&rgb); RGBForeColor(&rgb);
  196.     s = (unsigned char *)"\pHi";
  197.     SetRect(&r,0,0,StringWidth(s),textSize);
  198.     r.right+=0.3*textSize;    // Allow for slant of italic.
  199.     CenterRectInRect(&r,&window->portRect);
  200.     MoveTo(r.left,r.bottom);
  201.     DrawString(s);
  202.  
  203.     if(1){
  204.         /* Write a gray wedge, just for debugging, so we can examine clut */
  205.         SetRect(&wedge,0,0,20,256);
  206.         CenterRectInRect(&wedge,&window->portRect);
  207.         OffsetRect(&wedge,2-wedge.left,0);
  208.         pt.h=pt.v=0;
  209.         LocalToGlobal(&pt);
  210.         ShieldCursor(&wedge,pt);
  211.         for (j=0;j<256;j++){
  212.             row[0]=(long)clutSize*j/256;
  213.             row[0]*=multiplier;
  214.             for(i=0;i<20;i++)row[i]=row[0];
  215.             SetPixelsQuickly(wedge.left,j+wedge.top,row,20);
  216.         }
  217.         ShowCursor();
  218.         InsetRect(&wedge,-1,-1);
  219.         FrameRect(&wedge);
  220.     }
  221.  
  222.     /* Filter horizontally */
  223.     SetGDevice(device);                /* Use color table of that screen */
  224.     dstRect=r;                        /* dstRect just contains the string ... */
  225.     InsetRect(&dstRect,-dim/2,0);    /* extend dstRect to allow for the blur */
  226.     HLockHi((Handle)window->portPixMap);
  227.     ShieldCursor(&dstRect,pt);
  228.     ConvolveX(f,dim,(BitMap *) *window->portPixMap,(BitMap *) *window->portPixMap,
  229.         &window->portRect,&dstRect);
  230.     ShowCursor();
  231.  
  232.     /* Filter vertically */
  233.     InsetRect(&dstRect,0,-dim/2);    /* Extend dstRect to allow for the blur */
  234.     ShieldCursor(&dstRect,pt);
  235.     ConvolveY(f,dim,(BitMap *) *window->portPixMap,(BitMap *) *window->portPixMap,
  236.         &window->portRect,&dstRect);
  237.     ShowCursor();
  238.     SetGDevice(oldDevice);            /* Restore original device */
  239.  
  240.     GetFNum((StringPtr)"\pChicago",&FontNum);
  241.     TextFont(FontNum);
  242.     TextSize(12);
  243.     TextFace(0);
  244.     PmForeColor(0);                /* black in our current clut */
  245.     MoveTo(10,window->portRect.bottom-10);
  246.     DrawString((StringPtr)"\pDone. Click mouse or hit any key to exit.");
  247.     printf("Done. Click mouse or hit any key to exit.\n");
  248.     FlushEvents(everyEvent,0);
  249.     while(!GetNextEvent(keyDownMask+mDownMask,&event)) ;
  250.     SetGWorld(oldPort,oldDevice);
  251.     GDDisposeWindow(window);
  252.     // restore
  253.     GDRestoreGamma(device);
  254.     GDRestoreDeviceClut(device);
  255.     error=SetDepth(device,oldPixelSize,1<<gdDevType,oldIsColor);
  256.     #if (THINK_C || THINK_CPLUS || SYMANTEC_C)
  257.         abort();
  258.     #elif __MWERKS__
  259.         SIOUXSettings.autocloseonquit=1;
  260.     #endif
  261. }
  262.  
  263.